package com.cta.view.controller;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.cta.entity.Contact;
import com.cta.entity.PBX;
import com.cta.entity.Site;
import com.cta.service.SiteService;
import com.cta.utils.RequestUtils;
import com.cta.view.imports.Reader;
import com.cta.view.imports.impl.ExcelReader;
import com.cta.view.json.AssignUserJson;
import com.cta.view.json.BaseJson;
import com.cta.view.json.JsonObject;
import com.cta.view.json.SiteNodeJson;
import com.cta.view.json.UserJson;
import com.cta.view.json.UserViewJson;

@Controller
public class UserController extends BasicController {

	private final static String USER = "USER";

	@Autowired
	private SiteService siteService;

	@Autowired
	private MessageSource messageSource;

	@RequestMapping(value = "/user-info", method = RequestMethod.GET)
	@ResponseBody
	public JsonObject<UserJson> userInfo(Locale locale, Long userId) {
		try {
			List<Site> allSites = siteService.findAllSites();
			List<SiteNodeJson> sites = new ArrayList<SiteNodeJson>(allSites.size());

			for (Site site : allSites) {
				sites.add(new SiteNodeJson(String.valueOf(site.getId()), site.getName(), site.getDescription()));
			}
			UserJson uj = new UserJson();
			uj.setSites(sites);
			if (userId != null) {
				Contact contact = siteService.findContactById(userId);
				if (contact != null) {
					uj.setName(contact.getName());
					uj.setStation(contact.getStation());
					uj.setAuthorizationCode(contact.getAuthorizationCode());
					uj.setFullName(contact.getFullName());
					uj.setGender(contact.getGender().name());
					uj.setBirthDay(contact.getBirthDay());
					uj.setEmail(contact.getEmail());
					uj.setHome(contact.getHome());
					uj.setFax(contact.getFax());
					uj.setAddress(contact.getAddress());
					uj.setMobile(contact.getMobile());
					uj.setAssignTo(String.valueOf(contact.getAssignTo()));
					uj.setPassword(contact.getPassword());
				}
			}
			return JsonObject.newJsonObject(true, uj);
		} catch (Exception e) {
			log.error("Error: ", e);
			return JsonObject.emptyJsonObject();
		}
	}

	@RequestMapping(value = "/pbx-user-view", method = RequestMethod.GET)
	@ResponseBody
	public JsonObject<UserViewJson> userView(Locale locale, Long parentId) {
		try {
			List<Contact> allSites = siteService.findContactByParentId(parentId);
			List<PBX> pbxs = siteService.findPBXByParentId(parentId);
			// merge to list
			List<UserViewJson> contacts = new ArrayList<UserViewJson>(allSites.size() + pbxs.size());
			int i = 1;
			for (Contact c : allSites) {
				if (RequestUtils.isAdmin(c)) {
					contacts.add(new UserViewJson(String.valueOf(i++), c.getName(), "user-admin.png", String.valueOf(c
							.getId()), USER, true));
				} else {
					contacts.add(new UserViewJson(String.valueOf(i++), c.getName(), "user-thumb-1.png", String
							.valueOf(c.getId()), USER, false));
				}

			}
			for (PBX p : pbxs) {
				contacts.add(new UserViewJson(String.valueOf(i++), p.getName(), "phone.png", String.valueOf(p.getId()),
						PBXController.PBX));
			}
			Collections.sort(contacts, new Comparator<UserViewJson>() {
				public int compare(UserViewJson o1, UserViewJson o2) {
					return o1.getName().compareTo(o2.getName());
				}
			});
			return JsonObject.newJsonObject(true, contacts);
		} catch (Exception e) {
			log.error("Error: ", e);
			return JsonObject.emptyJsonObject();
		}
	}

	@RequestMapping(value = "/list-user-view", method = RequestMethod.GET)
	@ResponseBody
	public JsonObject<UserViewJson> listUserView(Locale locale, String type) {
		try {
			List<Contact> allContacts = null;
			if ("all".equals(type)) {
				allContacts = siteService.findAllContactExceptSuperAdmin();
			} else if ("admin".equals(type)) {
				allContacts = siteService.findAllAdminContact();
			} else if ("contact".equals(type)) {
				allContacts = siteService.findAllNormalContact();
			}
			// merge to list
			List<UserViewJson> contacts = new ArrayList<UserViewJson>(allContacts.size());
			for (Contact c : allContacts) {
				if (RequestUtils.isAdmin(c)) {
					contacts.add(new UserViewJson(null, c.getName(), "user-admin.png", String.valueOf(c.getId()), null));
				} else {
					contacts.add(new UserViewJson(null, c.getName(), "user-thumb-1.png", String.valueOf(c.getId()),
							null));
				}
			}
			return JsonObject.newJsonObject(true, contacts);
		} catch (Exception e) {
			log.error("Error: ", e);
			return JsonObject.emptyJsonObject();
		}
	}

	@RequestMapping(value = "/list-assign-user", method = RequestMethod.GET)
	@ResponseBody
	public JsonObject<AssignUserJson> listAssignUser(Locale locale, String type) {
		try {
			List<Site> allSites = siteService.findAllSites();
			List<SiteNodeJson> sites = new ArrayList<SiteNodeJson>(allSites.size());
			for (Site site : allSites) {
				sites.add(new SiteNodeJson(null, String.valueOf(site.getId()), site.getName(), site.getDescription()));
			}
			List<Contact> allContacts = siteService.findAllContactExceptSuperAdminAndNotAssign();
			// merge to list
			List<BaseJson> contacts = new ArrayList<BaseJson>(allContacts.size());
			for (Contact c : allContacts) {
				contacts.add(new BaseJson(null, String.valueOf(c.getId()), c.getName(), null));
			}
			return JsonObject.newJsonObject(true, new AssignUserJson(sites, contacts));
		} catch (Exception e) {
			log.error("Error: ", e);
			return JsonObject.emptyJsonObject();
		}
	}

	@RequestMapping(value = "/create-user", method = RequestMethod.POST)
	@ResponseBody
	public String createUser(Locale locale, String name, String station, String authorizationCode, String fullName,
			String gender, String birthday, String email, String mobile, String home, String fax, String password,
			Long assignTo, String address) {
		try {
			Contact contact = siteService.createUser(name, station, authorizationCode, fullName, gender, birthday,
					email, mobile, home, fax, password, assignTo, address);
			return String.format(
					"{'success':true, msg:'%s', obId: %s, name: '%s', thumb: 'user-thumb-1.png', type:'%s'}",
					"Create contact successful", contact.getId(), contact.getName(), USER);
		} catch (Exception e) {
			log.error("Error: ", e);
			return String.format("{'success':false, msg:'%s'}", "Fail to create contact");
		}
	}

	@RequestMapping(value = "/edit-user", method = RequestMethod.POST)
	@ResponseBody
	public String updateUser(Locale locale, Long userId, String name, String station, String authorizationCode,
			String fullName, String gender, String birthday, String email, String mobile, String home, String fax,
			String password, Long assignTo, String address) {
		try {
			Contact contact = siteService.updateUser(userId, name, station, authorizationCode, fullName, gender,
					birthday, email, mobile, home, fax, password, assignTo, address);
			return String.format(
					"{'success':true, msg:'%s', obId: %s, name: '%s', thumb: 'user-thumb-1.png', type:'%s'}",
					"Update contact successful", contact.getId(), contact.getName(), USER);
		} catch (Exception e) {
			log.error("Error: ", e);
			return String.format("{'success':false, msg:'%s'}", "Fail to update contact");
		}
	}

	@RequestMapping(value = "/set-as-admin", method = RequestMethod.POST)
	@ResponseBody
	public String setAdminRole(Locale locale, Long siteId, Long oldUserId, Long userId) {
		try {
			siteService.setAsAdminSite(siteId, oldUserId, userId);
			return String.format("{'success':true, msg:'%s', admin:{thumb: '%s'}, user: {thumb: '%s'}}", "Set as Admin ok", "user-admin.png", "user-thumb-1.png");
		} catch (Exception e) {
			log.error("Error: ", e);
			return String.format("{'success':false, msg:'%s'}", "Set as Admin fail");
		}
	}
	
	
	@RequestMapping(value = "/import-user", method = RequestMethod.POST)
	@ResponseBody
	public String importUser(FileUploadBean uploadItem, BindingResult result) {
		try {
			ExcelReader
					.getEndResults(uploadItem.getFile().getInputStream(), uploadItem.getFile().getOriginalFilename());
			return String.format("{'success':true, msg:'%s'}", "Success import user");
		} catch (Exception e) {
			log.error("Error: ", e);
			return String.format("{'success':false, msg:'%s'}", "Fail to import user");
		}
	}

	@RequestMapping(value = "/assign-user", method = RequestMethod.POST)
	@ResponseBody
	public String assignUser(Locale locale, Long assignTo, String itemselector) {
		try {
			siteService.assignUserToSite(assignTo, itemselector);
			return String.format("{ success: true, msg: '%s'}", "Assign all users ok");
		} catch (Exception e) {
			log.error("Error: ", e);
			return String.format("{ success: false, msg: '%s'}", "Assign users fail");
		}
	}

	@RequestMapping(value = "/un-assign-user", method = RequestMethod.POST)
	@ResponseBody
	public String unAssignUser(Locale locale, String userIds) {
		try {
			siteService.unAssignUserToSite(userIds);
			return String.format("{ success: true, msg: '%s'}", "Un Assign all users ok");
		} catch (Exception e) {
			log.error("Error: ", e);
			return String.format("{ success: false, msg: '%s'}", "Un Assign users fail");
		}
	}

}
